package com.behelpful.common.core.utils;


import com.behelpful.common.core.model.GeoPoint;
import com.behelpful.common.core.model.GeoRange;

/**
 * 地理位置信息工具类
 *
 * @author Alay
 * @date 2021-12-15 13:35
 */
public class IGeoUtil {

    /**
     * 地球半径（米）6357km到6378km,平均6371393米
     */
    private static final double EARTH_RADIUS = 6371393d;

    /**
     * 弧度转角度
     */
    public static final double RADIANS_TO_DEGREES = 180 / Math.PI;
    /**
     * 角度转弧度
     */
    public static final double DEGREES_TO_RADIANS = Math.PI / 180;

    /**
     * 根据中心点经纬度，计算半径范围内的经纬度范围
     *
     * @param center 中心点
     * @param dist   距离半径（米）
     * @return
     */
    public static GeoRange findPosition(final GeoPoint center, final double dist) {
        //先计算查询点的经纬度范围
        double lonRad = 2 * Math.asin(Math.sin(dist / (2 * EARTH_RADIUS)) / Math.cos(center.latitude() * Math.PI / 180));

        //角度转为弧度
        lonRad = lonRad * RADIANS_TO_DEGREES;
        double latRad = dist / EARTH_RADIUS;
        latRad = latRad * 180 / Math.PI;

        //经度最小值
        double minLon = center.getLongitude() - lonRad;
        //经度最大值
        double maxLon = center.longitude() + lonRad;
        //纬度最小值
        double minLat = center.latitude() - latRad;
        //纬度最大值
        double maxLat = center.latitude() + latRad;

        GeoRange geoRange = GeoRange.build().minLat(minLat).maxLat(maxLat).minLon(minLon).maxLon(maxLon);
        return geoRange;
    }

    /**
     * 求地球表面两点间的距离
     *
     * @param center 中心点坐标
     * @param target 目标点坐标
     * @return
     */
    public static double distance(final GeoPoint center, final GeoPoint target) {

        //计算中心点经纬度弧度
        double centerLonRad = center.longitude() * DEGREES_TO_RADIANS;
        double centerLatRad = center.latitude() * DEGREES_TO_RADIANS;

        //计算目标点经纬度弧度
        double targetLonRad = target.longitude() * DEGREES_TO_RADIANS;
        double targetLatRad = target.latitude() * DEGREES_TO_RADIANS;

        //计算经纬度的差
        double diffX = Math.abs(centerLonRad - targetLonRad);
        double diffY = Math.abs(centerLatRad - targetLatRad);

        //计算正弦
        double sinX = Math.sin(diffX / 2);
        double sinY = Math.sin(diffY / 2);

        //计算余弦
        double centerLatRad_cos = Math.cos(centerLatRad);
        double targetLatRad_cos = Math.cos(targetLatRad);

        double h = Math.pow(sinY, 2) + (centerLatRad_cos * targetLatRad_cos * Math.pow(sinX, 2));
        //两点的距离
        double dist = EARTH_RADIUS * 2 * Math.atan2(Math.sqrt(h), Math.sqrt(1 - h));
        return dist;
    }

}
